home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / NCSA / tn3270 2.4d7 source / NCSA⁄BYU TCP⁄IP / protinit.c < prev    next >
Text File  |  1991-06-27  |  9KB  |  333 lines

  1. /*
  2. *  Protinit.c
  3. *  initialize the template packets
  4. ****************************************************************************
  5. *                                                                          *
  6. *      part of:                                                            *
  7. *      TCP/UDP/ICMP/IP Network kernel for NCSA Telnet                      *
  8. *      by Tim Krauskopf                                                    *
  9. *                                                                          *
  10. *      National Center for Supercomputing Applications                     *
  11. *      152 Computing Applications Building                                 *
  12. *      605 E. Springfield Ave.                                             *
  13. *      Champaign, IL  61820                                                *
  14. *                                                                          *
  15. *    Copyright (c) 1987, Board of Trustees of the University of Illinois   *
  16. *                                                                          *
  17. ****************************************************************************
  18. *   'protinit' initializes packets to make them ready for transmission.
  19. *   For many purposes, pre-initialized packets are created for use by the
  20. *   protocol routines, especially to save time creating packets for
  21. *   transmit.
  22. *
  23. *   Assumes that 'myaddr' is already set to my Ethernet hardware address
  24. *   and any other similar protocol addresses are already initialized 
  25. *   (known) for the local station.
  26. *
  27. *   As this is a convenient place for it, this file contains many of the
  28. *   data declarations for packets which are mostly static (pre-allocated).
  29. */
  30. #include <stdio.h>
  31. #include <string.h>
  32.  
  33. #include <Events.h>
  34. #include <Memory.h>
  35.  
  36. #include "protocol.h"
  37. #include "data.h"
  38. #include "tools.h"
  39. #include "user.h"
  40.  
  41. /*************************************************************************/
  42. /*  Ethernet headers, initialize a default header to be used in 
  43. *   subsequent pre-initialized headers.  This does something similar for
  44. *   AppleTalk.
  45. */
  46.  
  47. void etherinit
  48.   (
  49.     void
  50.   )
  51.     {
  52.     movebytes(broadaddr,bseed,DADDLEN);
  53.     movebytes(blankd.dest,broadaddr,DADDLEN);    /* some are broadcast */
  54.     movebytes(blankd.me,nnmyaddr,DADDLEN);        /* always from me */
  55.  
  56.     blankd.type = EIP;                /* mostly IP packets */
  57.  
  58. }
  59.  
  60. /*************************************************************************/
  61. /*  ARP packets
  62. *
  63. *   a very limited type of packet goes out.  We currently only talk IP, so
  64. *   initialize as many fields as possible, most fields are already known.
  65. *
  66. *   Also initialize a reverse-arp packet to be sent out on request. (later)
  67. */
  68.  
  69. void arpinit
  70.   (
  71.     void
  72.   )
  73.     {
  74.     int i;
  75.  
  76.     movebytes(&arp.d,&blankd,sizeof(DLAYER));
  77.  
  78.     arp.d.type = EARP;                /* 0x0806 is ARP type */
  79.  
  80.     arp.hrd = intswap(HTYPE);            /*  Ether = 1 */
  81.     arp.pro = intswap(ARPPRO);            /* IP protocol = 0x0800 */
  82.     arp.hln = DADDLEN;                    /* Ethernet hardware length */
  83.     arp.pln = 4;                        /* IP length = 4 */
  84.     
  85.     movebytes(arp.sha,nnmyaddr,DADDLEN);    /* sender's hardware addr */
  86.     movebytes(arp.tha,broadaddr,DADDLEN);    /* target hardware addr */
  87.  
  88.     movebytes(arp.spa,nnipnum,4);        /* sender's IP addr */
  89.  
  90. /*
  91. *  initialize the ARP cache to 0 time, none are gateways to start
  92. */
  93.     for (i=0; i<CACHELEN; i++) {
  94.         arpc[i].tm = 0L;
  95.         arpc[i].gate = 0;
  96.     }
  97.  
  98. }
  99.  
  100. /*************************************************************************/
  101. /*  Internet protocol
  102. *   initialize one packet to use for arbitrary internet transmission.
  103. *   Hopefully, most outgoing IP packets will be pre-initialized by TCP or
  104. *   UDP, but some operations may require a generic IP packet.
  105. */
  106.  
  107. void ipinit
  108.   (
  109.     void
  110.   )
  111.     {
  112.     movebytes(&blankip.d,&blankd,sizeof(DLAYER));
  113.  
  114.     blankip.i.versionandhdrlen = 0x45;        /* smallest header, version 4 */
  115.     blankip.i.service = 0;                    /* normal service */
  116.  
  117.     blankip.i.tlen = 576;                        /* no data yet, maximum size */
  118.     blankip.i.ident = 0;
  119.     blankip.i.frags = 0;                        /* not a fragment of a packet */
  120.  
  121.     blankip.i.ttl = 100;                        /* 100 seconds should be enough */
  122.     blankip.i.protocol = PROTUDP;                /* default to UDP */
  123.  
  124.     blankip.i.check = 0;                        /* disable checksums for now */
  125.  
  126.     movebytes(blankip.i.ipsource,nnipnum,4);    /* my return address */
  127.     movebytes(blankip.i.ipdest,broadip,4);        /* to ? */
  128.  
  129. #ifdef notneedednow
  130. /*
  131. *  Make a blank ICMP packet for sending ICMP requests or responses
  132. */
  133.     movebytes(&blankicmp,&blankip,sizeof(DLAYER)+sizeof(IPLAYER));
  134.     blankicmp.i.protocol = PROTICMP;        
  135. #endif
  136.  
  137. /*
  138. *  create a mask which can determine whether a machine is on the same wire
  139. *  or not.  RFC950
  140. *  Only set the mask if not previously set.
  141. *  This mask may be replaced by a higher level request to set the subnet mask.
  142. */
  143.  
  144.     if (comparen(nnmask,"\0\0\0\0",4)) {            /* now blank */
  145.  
  146.         if (!(nnipnum[0] & 0x80))                    /* class A */
  147.             netsetmask(nnamask);
  148.         else if ((nnipnum[0] & 0xC0) == 0x80)        /* class B */
  149.             netsetmask(nnbmask);
  150.         else if ((nnipnum[0] & 0xC0) == 0xC0)        /* class C */
  151.             netsetmask(nncmask);
  152.     }
  153.  
  154. }
  155.  
  156. /**************************************************************************/
  157. /*  TCP stuff
  158. *     get ready for makeport()
  159. *   makeport() actually does the initialization when you open a port
  160. */
  161.  
  162. void tcpinit
  163.   (
  164.     void
  165.   )
  166.     {
  167.     int i;
  168.  
  169.     for (i=0; i < NPORTS; i++)
  170.         portlist[i] = NULL;            /* no ports open yet */
  171. }
  172.  
  173. /**************************************************************************/
  174. /*  UDP initialization
  175. *   set up ulist for receive of UDP packets
  176. */
  177.  
  178. void udpinit
  179.   (
  180.     void
  181.   )
  182.     {
  183.     ulist.stale = 1;
  184.     ulist.length = 0;
  185.  
  186.     movebytes(&ulist.udpout,&blankip,sizeof(DLAYER)+sizeof(IPLAYER));
  187.     ulist.udpout.i.protocol = PROTUDP;                /* UDP type */
  188.     ulist.tcps.z = 0;
  189.     ulist.tcps.proto = PROTUDP;
  190.     movebytes(ulist.tcps.source,nnipnum,4);
  191.     
  192. }
  193.  
  194. /************************************************************************/
  195. /*  main code for protinit()
  196. *   for each new type of protocol, put an initialization call here.
  197. *   There may be some requirement of order of initialization.
  198. */
  199. int protinit
  200.   (
  201.     void
  202.   )
  203.     {
  204.  
  205.     etherinit();
  206.     arpinit();  
  207.     ipinit();
  208.     tcpinit();
  209.     udpinit();
  210.  
  211.     return(0);
  212. }
  213.  
  214. void setupwindow
  215.   (
  216.     struct window *w,
  217.     unsigned int wsize
  218.   )
  219.     {
  220.     w->endbuf = w->where + wsize;
  221.     w->base = w->endlim = w->where;
  222.     w->contain = 0;                        /* nothing here yet */
  223.     w->lasttime = time(NULL);
  224.     w->size = wsize;
  225.     w->push = 0;
  226.  
  227. /*
  228. *  base this on time of day clock, for uniqueness
  229. */
  230.     w->ack = w->nxt = ((w->lasttime << 12) & 0x0fffffff);
  231.  
  232. }
  233.  
  234. /**************************************************************************/
  235. /*  makeport
  236. *
  237. *   This is the intialization for TCP based communication.  When a port
  238. *   needs to be created, this routine is called to do as much pre-initialization
  239. *   as possible to save overhead during operation.
  240. *
  241. *   This structure is created upon open of a port, either listening or 
  242. *   wanting to send.
  243. *
  244. *   A TCP port, in this implementation, includes all of the state data for the
  245. *   port connection, a complete packet for the TCP transmission, and two
  246. *   queues, one each for sending and receiving.  The data associated with
  247. *   the queues is in struct window.
  248. */
  249. int makeport
  250.   (
  251.     void
  252.   )
  253.     {
  254.     int i,j,retval;
  255.  
  256.     struct port *p,*q;
  257.  
  258. /*
  259. *  Check to see if any other connection is done with its port buffer space.
  260. *  Indicated by the connection state of SCLOSED
  261. */
  262.     p = NULL;
  263.     i = 0;
  264.     do {
  265.         q = portlist[i];
  266.         if (q != NULL && (q->state == SCLOSED ||
  267.         (q->state == STWAIT && q->out.lasttime + WAITTIME < time(NULL)))) 
  268.             p = q;
  269.         retval = i++;                    /* port # to return */
  270.     } while (p == NULL && i < NPORTS);
  271.  
  272. /*  
  273. * None available pre-allocated, get a new one, about 8.5 K with a 4K windowsize
  274. */
  275.     if (p == NULL) {
  276.         p = (struct port *)NewPtr(sizeof(struct port));
  277.  
  278.         for (i=0; portlist[i] != NULL; i++)
  279.             if (i >= NPORTS) {
  280.                 nnerror(500);
  281.                 return(-1);                /* out of room for ports */
  282.             }
  283.         portlist[i] = p;
  284.         retval = i;
  285.     }
  286.  
  287.     if (p == NULL) {
  288.         nnerror(505);
  289.         return(-1);
  290.     }
  291.  
  292.     movebytes(&p->tcpout,&blankip,sizeof(DLAYER)+sizeof(IPLAYER));
  293.                                             /* static initialization */
  294.  
  295.     p->tcpout.i.tlen = 0;
  296.     p->tcpout.t.urgent = 0;                    /* no urgent data */
  297.     p->tcpout.t.hlen = 20 << 2;                /* header length << 2 */
  298.     p->tcps.z = 0;
  299.     p->tcps.proto = PROTTCP;
  300.     movebytes(p->tcps.source,nnipnum,4);
  301.  
  302.     setupwindow(&p->in,WINDOWSIZE);        /* queuing parameters */
  303.     setupwindow(&p->out,WINDOWSIZE);
  304.  
  305.     do {
  306.  
  307.         i = time(NULL);
  308.         i |= 2048;              /* make sure it is at least this large */
  309.         i &= 0x3fff;            /* at least this small */
  310.  
  311.         for (j=0; j<NPORTS && i != portlist[j]->in.port ; j++)
  312.             ;
  313.  
  314.     } while (j < NPORTS);
  315.  
  316.     if ( nnfromport ) {            /* allow the from port to be forced */
  317.         i = nnfromport;
  318.         nnfromport = 0;
  319.     }
  320.  
  321.     p->in.port = i;
  322.  
  323.     p->tcpout.t.source = intswap(i);
  324.     p->tcpout.t.seq = longswap(p->out.nxt);
  325.     
  326.     p->state = SCLOSED;
  327.     p->credit = nncredit;
  328.     p->sendsize = TSENDSIZE;
  329.     p->rto = MINRTO;
  330.  
  331.     return(retval);
  332. }
  333.